home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-11 / trudf.zip / SOUNDEX.C < prev    next >
Text File  |  1993-01-04  |  6KB  |  152 lines

  1. /******************************
  2. * Compiled : with Microsoft C 5.1
  3. * Object   : can only be used in conjunction with Clipper summer '87
  4. * Syntax   : SOUNDEX( <xpC> )
  5. * Parameter: string of any length without embedded null bytes
  6. *            and terminated with a null byte.
  7. * Return   : A string of 5 characters long containing the soundex code
  8. * Author   : Jean-Pierre van Melis, Helmond, The Netherlands
  9. * Date     : June 1, 1988
  10. * Note..   : There is 1 difference with the SOUNDEX function from clipper.
  11. *            the trailing characters are SPACEs instead of zeros.
  12. *
  13. *            this routine is 3 times faster than the internal clipper function.
  14. *            and it always returns a string of 5 characters (so you can
  15. *            use code like:
  16.  
  17.                               INDEX ON SOUNDEX(name) TO SND_name
  18.                               SEEK TRIM(SOUNDEX(mNAME))
  19. *
  20. *            A E H I O U W Y                group  0
  21. *            B F P V                        group  1
  22. *            C G J K Q S X Z Ç ç            group  2
  23. *            D T                            group  3
  24. *            L                              group  4
  25. *            M N                            group  5
  26. *            R                              group  6
  27. *            (including lowercase)
  28. *
  29. *            all other characters are discarded.
  30. *
  31. *     CLIPPER's  routine                My routine
  32. *     -------------------               ------------------
  33. *  SOUNDEX("Nantucket") == "N532"  <==> SOUNDEX("Nantucket") == "N5323"
  34. *  SOUNDEX("Mantucket") == "M532"  <==> SOUNDEX("Mantucket") == "M5323"
  35. *  SOUNDEX("extend")    == "E235"  <==> SOUNDEX("extend")    == "E2353"
  36. *
  37. *  SOUNDEX("         ") == ""      <==> SOUNDEX("         ") == "     "
  38. *  SOUNDEX("X")         == "X000"  <==> SOUNDEX("X")         == "X    " 
  39. *
  40. *  Execution time:
  41. *                  0.0084 seconds  <==> 0.0033 seconds (using Turbo C 1.0)
  42. *  Size:  
  43. *   Source :          3184 bytes   <==> 1884 bytes (both without comments)
  44. *   Object :          1234 bytes   <==> 795  bytes (both using turbo C)
  45. *                                  <==> 752  bytes (using MSC 5.1)
  46. *
  47. *  When comparing speed, I used the routine out of extend.lib.
  48. *  When comparing size, I used the routine out of examplec.c and compiled
  49. *  it with Turbo C.
  50. *  Results are probably better when using Microsoft C 5.x 
  51. *
  52. *  If you replace the line ' #define COMPATIBLE FALSE ' with
  53. *  ' #define COMPATIBLE TRUE ', and recompile it with Microsoft C 5.x
  54. *  the soundex routine is almost the same as the internal routine
  55. *  (only faster, and always returning a valid soundex code)
  56. *
  57. ***********/
  58. #include "jplib.h"
  59.  
  60. #define COMPATIBLE FALSE
  61.  
  62. #if (COMPATIBLE)
  63.    #define INIT      '0'
  64.    static byte result[5] = {INIT,INIT,INIT,INIT,'\0'};
  65. #else
  66.    #define INIT      ' '
  67.    static byte result[6] = {INIT,INIT,INIT,INIT,INIT,'\0'};
  68. #endif
  69.  
  70.  
  71. /*                A   B   C   D   E   F   G   H   I   J   K   L   M  */
  72.  
  73. #define ALPH1    ' ','1','2','3',' ','1','2',' ',' ','2','2','4','5'
  74. #define ALPH2    '5',' ','1','2','6','2','3',' ','1',' ','2',' ','2'
  75.  
  76. /*                N   O   P   Q   R   S   T   U   V   W   X   Y   Z  */
  77.  
  78. #define SPACE    ' '
  79. #define SPACE5   ' ',' ',' ',' ',' '
  80.  
  81. #define SPACE10  SPACE5,SPACE5
  82. #define SPACE20  SPACE10,SPACE10
  83. #define SPACE40  SPACE20,SPACE20
  84. #define SPACE65  SPACE40,SPACE20,SPACE5
  85. #define SPACE120 SPACE40,SPACE40,SPACE40
  86.  
  87.  
  88. static byte code_string[256]= { SPACE65,
  89.                                 ALPH1,          /* A...M  */
  90.                                 ALPH2,          /* N...Z  */
  91.                                 SPACE5,SPACE,   /* [\]^_` */
  92.                                 ALPH1,          /* a...m  */
  93.                                 ALPH2,          /* n...z  */
  94.                                 SPACE5,
  95. #if (COMPATIBLE)
  96.                                 SPACE,
  97. #else
  98.                                 '2',            /* Ç      */
  99. #endif
  100.                                 SPACE5,SPACE,
  101. #if (COMPATIBLE)
  102.                                 SPACE,
  103. #else
  104.                                 '2',            /* Ç      */
  105. #endif
  106.                                 SPACE120
  107.                                };
  108.  
  109. CLIPPER SOUNDEX()
  110.  
  111. {
  112.  byte     *in_ptr;
  113.  byte     *res_ptr;
  114.  byte     code;
  115.  byte     lastcode;
  116.  
  117.  in_ptr   = _parc(1);              /* receive string from clipper */
  118.  
  119.  result[0]= INIT;                  /* initialize result with INIT. */
  120.  result[1]= INIT;                  /* because the result gets overwritten */
  121.  result[2]= INIT;                  /* each time the function is called. */
  122.  result[3]= INIT;                  /* only the null byte stays the same. */
  123. #if ! (COMPATIBLE)
  124.  result[4]= INIT;
  125. #endif
  126.  res_ptr  = result;                /* res_ptr is pointer to result */
  127.  
  128.  if ISCHAR(1)                       /* parameter is a character string */
  129.  {
  130.   if(*in_ptr)                              /* string may be empty */    
  131.   {
  132.     lastcode   = SPACE;             /* initialize lastcode */
  133.     *res_ptr++ = toupper(*in_ptr);  /* convert to uppercase */
  134.     *in_ptr++;                      /* increment input pointer */
  135.     while((*res_ptr) && (*in_ptr))  /* while not end of string */
  136.     {
  137.       code = code_string[*in_ptr++];/* get code out of code_string */
  138.       if (code != SPACE)            /* is it a valid code */
  139.       {
  140.         if (code != lastcode)       /* is it different */
  141.         {
  142.           lastcode    = code;       /* save last used code */
  143.           *res_ptr++  = code;       /* put code into result */
  144.         }
  145.       }
  146.     }
  147.   }
  148.  }
  149.  _retc(result);                      /* return result to clipper */
  150.  return;                             /* return to clipper */
  151. }
  152.